﻿using ClosedXML.Excel;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using NLog;
using Opc.Ua;
using SHRIS.MIS.Common.Util.Extension;
using SHRIS.MIS.Data.Repository;
using SHRIS.MIS.Entity.ScadaBaseInfo;
using SHRIS.MIS.Entity.ScadaData;
using SHRIS.MIS.IService.APIExternal;
using SHRIS.MIS.Model.Param.APIExternal;
using SHRIS.MIS.Service.Device;
using SHRIS.MIS.Service.OpcService;
using ShrisCommunicationCore.OpcUa;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using System.Threading.Tasks;

namespace SHRIS.MIS.Service.LinePlantService
{
    public class LinePlantService: RepositoryFactory
    {
        private readonly IOptions<List<OpcServerDescriptionEntity>> _options;
        private readonly ILogger<LinePlantService> _logger;

        #region BitArray转INT

        public static int BitArrayToInt(BitArray bit)
        {
            int res = 0;
            for(int i = bit.Count - 1; i >= 0; i--)
            {
                res = bit[i] ? res + (1 << i) : res;
            }
            return res;
        }

        #endregion

        /// <summary>
        /// 所有数据库存在的opc服务器
        /// </summary>
        protected List<OpcServerDescriptionEntity> avaliableOpcServers=new List<OpcServerDescriptionEntity>();

        /// <summary>
        /// 数据库中配置的产线的所有设备
        /// </summary>
        protected IEnumerable<DeviceEntity> configuredDevices;

        /// <summary>
        /// opc设备及其对应的opc数据地址描述，该设备的opcDataSource地址在数据库中有对应服务器。
        /// string=deviceCode,IEnumerable=地址列表
        /// </summary>
        protected Dictionary<string, IEnumerable<OpcDataSourceEntity>> avaliableOpcDeivceDataSources = new Dictionary<string, IEnumerable<OpcDataSourceEntity>>();

        /// <summary>
        /// 产线所有的数据库中配置的设备实例，不单单是opc 设备
        /// </summary>
        protected List<BasicDevice> basicDevices=new List<BasicDevice>();


        /// <summary>
        /// 产线的通讯平台
        /// </summary>
        protected WorkshopCommunicationService workshopCommunicationService;

        //protected List<OpcServerConnection> opcServerConnections = new List<OpcServerConnection>();
        

        //protected LineManager _lineManager;

        public LinePlantService(IOptions<List<OpcServerDescriptionEntity>> options, ILogger<LinePlantService> logger)
        {
            _options = options ?? throw new ArgumentNullException(nameof(options));
            _logger = logger;
        }

        public async Task CreateWorkshop()
        {
            //获取数据库中配置的产线的所有设备
            try
            {
                configuredDevices = await SearchAllDevice();
            }
            catch(Exception ex)
            {
                throw ex;
            }
            


            #region 创建可用的OPC数据地址集
            //获取配置文件中配置的数据库中存在opc服务器
            foreach (var s in _options.Value)
            {
                var opcServer = await SerarchOpcServerById(s.Id);
                if (opcServer != null)
                {
                    foreach(OpcServerDescriptionEntity server in opcServer)
                    {
                        avaliableOpcServers.Add(server);
                    }                   
                }

            }

            if(avaliableOpcServers != null && avaliableOpcServers.Count()>0)
            {
                IEnumerable<Guid> avaliableServerIds = avaliableOpcServers.Select(i => i.Id);

                //获取所有设备的在可用服务器列表中的 opcDataSource 地址
                foreach (var d in configuredDevices)
                {
                    var avaliableDeviceOpcDataSources = await GetOpcDataSourceByServerIdsAndDeviceCode(avaliableServerIds,d.DeviceCode);
                    if (avaliableDeviceOpcDataSources != null && avaliableDeviceOpcDataSources.Count() > 0)
                    {
                        avaliableOpcDeivceDataSources.Add(d.DeviceCode, avaliableDeviceOpcDataSources);
                    }

                }

                #endregion

                //创建其他通讯地址集  to do 

                //创建通讯平台
                workshopCommunicationService = new WorkshopCommunicationService(avaliableOpcServers, _logger);

                try
                {
                    //连接到相关opc服务器
                    await workshopCommunicationService.ConnectToServers();

                }
                catch (Exception ex)
                {

                }
               
                //创建所有设备实例
                CreateDevices();
            }




        }


        /// <summary>
        /// 创建产线中的所有设备，不单单是OPC设备
        /// </summary>
        /// <returns></returns>
        private void CreateDevices()
        {
            foreach(var d in configuredDevices)
            {
                //获取该设备opc 数据地址
                IEnumerable<OpcDataSourceEntity> opcDataSourceEntities;
                avaliableOpcDeivceDataSources.TryGetValue(d.DeviceCode,out opcDataSourceEntities);

                try
                {
                    switch (d.DeviceTypeCode)
                    {
                        case 1:
                            {
                                WashMachine_01 washMachine_01 = new WashMachine_01(d, workshopCommunicationService, opcDataSourceEntities);
                                washMachine_01.PropertyChanged += MonitorPropertyChanged;
                                washMachine_01.InitalDevice();
                                basicDevices.Add(washMachine_01);
                                break;
                            }
                        case 2:
                            {
                                HoleDepthMeasure_02 holeDepthMeasure_02 = new HoleDepthMeasure_02(d, workshopCommunicationService, opcDataSourceEntities);
                                holeDepthMeasure_02.PropertyChanged += MonitorPropertyChanged;
                                holeDepthMeasure_02.InitalDevice();
                                basicDevices.Add(holeDepthMeasure_02);
                                break;
                            }
                        case 4:
                            {
                                RouthLathe_04 routhLathe_04 = new RouthLathe_04(d, workshopCommunicationService, opcDataSourceEntities);
                                routhLathe_04.PropertyChanged += MonitorPropertyChanged;
                                routhLathe_04.InitalDevice();
                                basicDevices.Add(routhLathe_04);
                                break;
                            }
                        case 5:
                            {
                                FineLathe_05 fineLathe_05 = new FineLathe_05(d, workshopCommunicationService, opcDataSourceEntities);
                                fineLathe_05.PropertyChanged += MonitorPropertyChanged;
                                fineLathe_05.InitalDevice();
                                basicDevices.Add(fineLathe_05);
                                break;
                            }
                        case 6:
                            {
                                LaserMark_06 laserMark_06 = new LaserMark_06(d, workshopCommunicationService, opcDataSourceEntities);
                                laserMark_06.PropertyChanged += MonitorPropertyChanged;
                                laserMark_06.InitalDevice();
                                basicDevices.Add(laserMark_06);
                                break;
                            }
                        case 8:
                            {
                                TrackRobot_08 trackRobot_08 = new TrackRobot_08(d, workshopCommunicationService, opcDataSourceEntities);
                                trackRobot_08.PropertyChanged += MonitorPropertyChanged;
                                trackRobot_08.InitalDevice();
                                basicDevices.Add(trackRobot_08);
                                break;
                            }
                        case 9:
                            {
                                Manipulator_09 manipulator_09 = new Manipulator_09(d, workshopCommunicationService, opcDataSourceEntities);
                                manipulator_09.PropertyChanged += MonitorPropertyChanged;
                                manipulator_09.InitalDevice();
                                basicDevices.Add(manipulator_09);
                                break;
                            }
                        case 10:
                            {
                                CacheStation_10 cacheStation_10 = new CacheStation_10(d, workshopCommunicationService, opcDataSourceEntities);
                                cacheStation_10.PropertyChanged += MonitorPropertyChanged;
                                cacheStation_10.InitalDevice();
                                basicDevices.Add(cacheStation_10);
                                break;
                            }
                        case 11:
                            {
                                ThreeCoordinatesMeasure_11 threeCoordinatesMeasure_11 = new ThreeCoordinatesMeasure_11(d, workshopCommunicationService, opcDataSourceEntities);
                                threeCoordinatesMeasure_11.PropertyChanged += MonitorPropertyChanged;
                                threeCoordinatesMeasure_11.InitalDevice();
                                basicDevices.Add(threeCoordinatesMeasure_11);
                                break;
                            }
                        case 12:
                            {
                                MainPlc_12 mainPlc_12 = new MainPlc_12(d, workshopCommunicationService, opcDataSourceEntities);
                                mainPlc_12.PropertyChanged += MonitorPropertyChanged;
                                mainPlc_12.InitalDevice();
                                basicDevices.Add(mainPlc_12);
                                break;
                            }
                        case 13:
                            {
                                Scanner_13 scanner_13 = new Scanner_13(d, workshopCommunicationService, opcDataSourceEntities);
                                scanner_13.PropertyChanged += MonitorPropertyChanged;
                                scanner_13.InitalDevice();
                                basicDevices.Add(scanner_13);
                                break;
                            }
                        default:
                            break;
                    }
                }
                catch(Exception ex)
                {

                }               
            }
        }

        /**
         * LYC修改于2021.4.25
         * workshopCommunicationService加上null值判断，避免没有连上opc时，空值调用异常
         */
        public IEnumerable<OpcServerStatusDto> GetOpcServerStatus()
        {
            if (workshopCommunicationService == null)
            {
                List<OpcServerStatusDto> list= new List<OpcServerStatusDto>();
                list.Add(new OpcServerStatusDto());
                return list;
            }
            else
            {
                return workshopCommunicationService.GetOpcServerStatus();
            }
           
        }


        #region 各个设备抛出来的值处理
        public void MonitorPropertyChanged(object sender, DeviceValueChangedEventArgs e)
        {
            switch(e.DeviceEntity.DeviceCode)
            {
                case "MainPlcControl":
                    {
                        switch(e.PropertyName)
                        {
                            case "OrderControlMode":
                                {
                                    OrderControlMode = (bool)e.CurrentValue;
                                    DeviceStatusEntity statusEntity = new DeviceStatusEntity {
                                        DeviceCode = e.DeviceEntity.DeviceCode,
                                        StatusCode = 1,
                                        StatusDescription = OrderControlMode ? "远程模式" : "本地模式",
                                        OPType = OrderControlMode ? 1 : 0,
                                    };

                                    Task.Run(()=> SaveDeviceStatus(statusEntity));
                                    break;
                                }
                            case "ManualStatus":
                                {
                                    ManualStatus = (bool)e.CurrentValue;
                                    break;
                                }
                            case "AutoStatus":
                                {
                                    AutoStatus = (bool)e.CurrentValue;
                                    break;
                                }
                            case "FirstpieceStatus":
                                {
                                    FirstpieceStatus = (bool)e.CurrentValue;
                                    break;
                                }
                            case "AutoReadyStatus":
                                {
                                    AutoReadyStatus = (bool)e.CurrentValue;
                                    break;
                                }
                            case "AutoRunStatus":
                                {
                                    AutoRunStatus = (bool)e.CurrentValue;
                                    break;
                                }
                            case "AutoStopStatus":
                                {
                                    AutoStopStatus = (bool)e.CurrentValue;
                                    break;
                                }
                            case "AllRestartStatus":
                                {
                                    AllRestartStatus = (bool)e.CurrentValue;
                                    break;
                                }
                            case "SuspendStatus":
                                {
                                    SuspendStatus = (bool)e.CurrentValue;
                                    break;
                                }
                            case "BypassStatus_01":
                                {
                                    BypassStatus_01 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "BypassStatus_02":
                                {
                                    BypassStatus_02 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "BypassStatus_03":
                                {
                                    BypassStatus_03 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "EMO_01":
                                {
                                    EMO_01 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "EMO_02":
                                {
                                    EMO_02 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "EMO_03":
                                {
                                    EMO_03 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "Ready_01":
                                {
                                    Ready_01 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "Ready_02":
                                {
                                    Ready_02 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "Ready_03":
                                {
                                    Ready_03 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "End_01":
                                {
                                    End_01 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "End_02":
                                {
                                    End_02 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "End_03":
                                {
                                    End_03 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "HasWorkpiece_01":
                                {
                                    HasWorkpiece_01 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "HasWorkpiece_02":
                                {
                                    HasWorkpiece_02 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "HasWorkpiece_03":
                                {
                                    HasWorkpiece_03 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "WorkpieceSource_01":
                                {
                                    WorkpieceSource_01 = (short)e.CurrentValue;
                                    break;
                                }
                            case "WorkpieceSource_02":
                                {
                                    WorkpieceSource_02 = (short)e.CurrentValue;
                                    break;
                                }
                            case "WorkpieceSource_03":
                                {
                                    WorkpieceSource_03 = (short)e.CurrentValue;
                                    break;
                                }
                            case "DayOff":
                                {
                                    DayOff = (bool)e.CurrentValue;
                                    break;
                                }
                            case "DayOffStatus":
                                {
                                    DayOffStatus = (bool)e.CurrentValue;
                                    break;
                                }

                            default:
                                break;
                        }
                        break;
                    }
                case "HoleDepthMeasure":
                    {
                        switch (e.PropertyName)
                        {
                            case "BypassStatus":
                                {
                                    _02_BypassStatus = (bool)e.CurrentValue;
                                    break;
                                }
                            case "EMO":
                                {
                                    _02_EMO= (bool)e.CurrentValue;
                                    break;
                                }
                            case "Ready":
                                {
                                    _02_Ready= (bool)e.CurrentValue;
                                    break;
                                }
                            case "End":
                                {
                                    _02_End= (bool)e.CurrentValue;
                                    break;
                                }
                            case "HasWorkpiece":
                                {
                                    _02_HasWorkpiece = (bool)e.CurrentValue;
                                    break;
                                }
                            case "RealCount":
                                {
                                    _02_RealCount = (short)e.CurrentValue;
                                    break;
                                }
                            case "WorkpieceSource":
                                {
                                    _02_WorkpieceSource = (short)e.CurrentValue;
                                    break;
                                }
                            case "CountSet":
                                {
                                    _02_CountSet = (short)e.CurrentValue;
                                    break;
                                }
                            case "MaterialCode":
                                {
                                    _02_MaterialCode = (string)e.CurrentValue;
                                    break;
                                }
                            case "Depth":
                                {
                                    _02_Depth = (double)e.CurrentValue;
                                    break;
                                }
                            case "HoLength":
                                {
                                    _02_HoLength = (double)e.CurrentValue;
                                    break;
                                }
                            case "ValAct":
                                {
                                    _02_ValAct = (bool)e.CurrentValue;
                                    if (_02_ValAct)
                                    {
                                        // 记录到数据库
                                        ProductionHoleDepthEntity entity = new ProductionHoleDepthEntity();
                                        entity.ProductionId = _02_MaterialCode;
                                        entity.DeviceCode = "HoleDepthMeasure";
                                        entity.Depth = _02_Depth;
                                        entity.Length = _02_HoLength;
                                        entity.UpdateTime = DateTimeOffset.Now;
                                        Task.Run(() => SaveProductionHoleDepth(entity));
                                    }
                                    break;
                                }
                            case "DMEquStaW":
                                {
                                    _02_DMEquStaW = (BitArray)e.CurrentValue;
                                    break;
                                }
                            case "DMEquProStaW":
                                {
                                    _02_DMEquProStaW = (BitArray)e.CurrentValue;
                                    break;
                                }
                            case "DMEquAlarmW_1":
                                {
                                    _02_DMEquAlarmW_1 = (BitArray)e.CurrentValue;
                                    break;
                                }
                            case "DMEquAlarmW_2":
                                {
                                    _02_DMEquAlarmW_2 = (BitArray)e.CurrentValue;
                                    break;
                                }
                            case "DMEquActProNo":
                                {
                                    _02_DMEquActProNo = e.CurrentValue.ToString();
                                    break;
                                }
                            case "DMEquStartEquTime":
                                {
                                    _02_DMEquStartEquTime = (DateTimeOffset)e.CurrentValue;
                                    break;
                                }
                            case "DMEquRunningTime":
                                {
                                    _02_DMEquRunningTime = (double)e.CurrentValue;
                                    break;
                                }
                        }
                        break;
                    }
                case "CacheStation01":
                    {
                        switch (e.PropertyName)
                        {
                            case "HasWorkpiece":
                                {
                                    _10_HasWorkpiece_1 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "WorkpieceSource":
                                {
                                    _10_WorkpieceSource_1 = (short)e.CurrentValue;
                                    break;
                                }
                            case "MaterialCode":
                                {
                                    _10_MaterialCode_1 = (string)e.CurrentValue;
                                    /**
                                     * 记录到数据库
                                     * tb_passInformation
                                     */
                                    PassInformationEntity entity = new PassInformationEntity();
                                    entity.ProductionId = _10_MaterialCode_1;
                                    entity.DeviceCode = "CacheStation01";
                                    entity.Program = "null";
                                    entity.ActionMode = 1;
                                    Task.Run(() => SavePassInformation(entity));
                                    break;
                                }
                        }
                        break;
                    }
                case "CacheStation02":
                    {
                        switch (e.PropertyName)
                        {
                            case "HasWorkpiece":
                                {
                                    _10_HasWorkpiece_2 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "WorkpieceSource":
                                {
                                    _10_WorkpieceSource_2 = (short)e.CurrentValue;
                                    break;
                                }
                            case "MaterialCode":
                                {
                                    _10_MaterialCode_2 = (string)e.CurrentValue;
                                    /**
                                     * 记录到数据库
                                     * tb_passInformation
                                     */
                                    PassInformationEntity entity = new PassInformationEntity();
                                    entity.ProductionId = _10_MaterialCode_2;
                                    entity.DeviceCode = "CacheStation02";
                                    entity.Program = "null";
                                    entity.ActionMode = 1;
                                    Task.Run(() => SavePassInformation(entity));
                                    break;
                                }
                        }
                        break;
                    }
                case "CacheStation03":
                    {
                        switch (e.PropertyName)
                        {
                            case "HasWorkpiece":
                                {
                                    _10_HasWorkpiece_3 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "WorkpieceSource":
                                {
                                    _10_WorkpieceSource_3 = (short)e.CurrentValue;
                                    break;
                                }
                            case "MaterialCode":
                                {
                                    _10_MaterialCode_3 = (string)e.CurrentValue;
                                    /**
                                     * 记录到数据库
                                     * tb_passInformation
                                     */
                                    PassInformationEntity entity = new PassInformationEntity();
                                    entity.ProductionId = _10_MaterialCode_3;
                                    entity.DeviceCode = "CacheStation03";
                                    entity.Program = "null";
                                    entity.ActionMode = 1;
                                    Task.Run(() => SavePassInformation(entity));
                                    break;
                                }
                        }
                        break;
                    }
                case "CacheStation04":
                    {
                        switch (e.PropertyName)
                        {
                            case "HasWorkpiece":
                                {
                                    _10_HasWorkpiece_4 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "WorkpieceSource":
                                {
                                    _10_WorkpieceSource_4 = (short)e.CurrentValue;
                                    break;
                                }
                            case "MaterialCode":
                                {
                                    _10_MaterialCode_4 = (string)e.CurrentValue;
                                    /**
                                     * 记录到数据库
                                     * tb_passInformation
                                     */
                                    PassInformationEntity entity = new PassInformationEntity();
                                    entity.ProductionId = _10_MaterialCode_4;
                                    entity.DeviceCode = "CacheStation04";
                                    entity.Program = "null";
                                    entity.ActionMode = 1;
                                    Task.Run(() => SavePassInformation(entity));
                                    break;
                                }
                        }
                        break;
                    }
                case "CacheStation05":
                    {
                        switch (e.PropertyName)
                        {
                            case "HasWorkpiece":
                                {
                                    _10_HasWorkpiece_5 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "WorkpieceSource":
                                {
                                    _10_WorkpieceSource_5 = (short)e.CurrentValue;
                                    break;
                                }
                            case "MaterialCode":
                                {
                                    _10_MaterialCode_5 = (string)e.CurrentValue;
                                    /**
                                     * 记录到数据库
                                     * tb_passInformation
                                     */
                                    PassInformationEntity entity = new PassInformationEntity();
                                    entity.ProductionId = _10_MaterialCode_5;
                                    entity.DeviceCode = "CacheStation05";
                                    entity.Program = "null";
                                    entity.ActionMode = 1;
                                    Task.Run(() => SavePassInformation(entity));
                                    break;
                                }
                        }
                        break;
                    }
                case "CacheStation06":
                    {
                        switch (e.PropertyName)
                        {
                            case "HasWorkpiece":
                                {
                                    _10_HasWorkpiece_6 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "WorkpieceSource":
                                {
                                    _10_WorkpieceSource_6 = (short)e.CurrentValue;
                                    break;
                                }
                            case "MaterialCode":
                                {
                                    _10_MaterialCode_6 = (string)e.CurrentValue;
                                    /**
                                     * 记录到数据库
                                     * tb_passInformation
                                     */
                                    PassInformationEntity entity = new PassInformationEntity();
                                    entity.ProductionId = _10_MaterialCode_6;
                                    entity.DeviceCode = "CacheStation06";
                                    entity.Program = "null";
                                    entity.ActionMode = 1;
                                    Task.Run(() => SavePassInformation(entity));
                                    break;
                                }
                        }
                        break;
                    }
                case "DownCar01":
                    {
                        switch (e.PropertyName)
                        {
                            case "AtStation":
                                {
                                    _08_AtStation_D1 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "Full":
                                {
                                    _08_Full_D1 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "WorkpieceNum":
                                {
                                    _08_WorkpieceNum_D1 = (short)e.CurrentValue;
                                    break;
                                }
                            case "MaterialCode":
                                {
                                    _08_MaterialCode_D1 = e.CurrentValue.ToString();
                                    /**
                                     * 记录到数据库
                                     */
                                    PassInformationEntity entity = new PassInformationEntity();
                                    entity.ProductionId = _08_MaterialCode_D1;
                                    entity.DeviceCode = "DownCar01";
                                    entity.Program = "null";
                                    entity.ActionMode = 1;
                                    Task.Run(() => SavePassInformation(entity));
                                    /**
                                     * 记录最终结果
                                     * 0:未开始  1：加工中  2：加工完成 3:返修中 4：加工失败
                                     */
                                    ProductionEntity productionEntity = new ProductionEntity();
                                    productionEntity.ProductionId = _08_MaterialCode_D1;
                                    productionEntity.ProductionResult = 2;
                                    productionEntity.UpdateTime = DateTimeOffset.Now;
                                    Task.Run(() => SaveProduction(productionEntity));
                                    break;
                                }
                        }
                        break;
                    }
                case "DownCar02":
                    {
                        switch (e.PropertyName)
                        {
                            case "AtStation":
                                {
                                    _08_AtStation_D2 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "Full":
                                {
                                    _08_Full_D2 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "WorkpieceNum":
                                {
                                    _08_WorkpieceNum_D2 = (short)e.CurrentValue;
                                    break;
                                }
                            case "MaterialCode":
                                {
                                    _08_MaterialCode_D2 = e.CurrentValue.ToString();
                                    /**
                                     * 记录到数据库
                                     */
                                    PassInformationEntity entity = new PassInformationEntity();
                                    entity.ProductionId = _08_MaterialCode_D2;
                                    entity.DeviceCode = "DownCar02";
                                    entity.Program = "null";
                                    entity.ActionMode = 1;
                                    Task.Run(() => SavePassInformation(entity));
                                    /**
                                     * 记录最终结果
                                     * 0:未开始  1：加工中  2：加工完成 3:返修中 4：加工失败
                                     */
                                    ProductionEntity productionEntity = new ProductionEntity();
                                    productionEntity.ProductionId = _08_MaterialCode_D2;
                                    productionEntity.ProductionResult = 2;
                                    productionEntity.UpdateTime = DateTimeOffset.Now;
                                    Task.Run(() => SaveProduction(productionEntity));
                                    break;
                                }
                        }
                        break;
                    }
                case "LoadCar01":
                    {
                        switch (e.PropertyName)
                        {
                            case "AtStation":
                                {
                                    _08_AtStation_L1 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "Empty":
                                {
                                    _08_Empty_L1 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "WorkpieceNum":
                                {
                                    _08_WorkpieceNum_L1 = (short)e.CurrentValue;
                                    break;
                                }
                            case "MaterialCode":
                                {
                                    _08_MaterialCode_L1 = e.CurrentValue.ToString();
                                    /**
                                     * 记录到数据库
                                     */
                                    PassInformationEntity entity = new PassInformationEntity();
                                    entity.ProductionId = _08_MaterialCode_L1;
                                    entity.DeviceCode = "LoadCar01";
                                    entity.Program = "null";
                                    entity.ActionMode = 1;
                                    Task.Run(() => SavePassInformation(entity));
                                    break;
                                }
                        }
                        break;
                    }
                case "LoadCar02":
                    {
                        switch (e.PropertyName)
                        {
                            case "AtStation":
                                {
                                    _08_AtStation_L2 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "Empty":
                                {
                                    _08_Empty_L2 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "WorkpieceNum":
                                {
                                    _08_WorkpieceNum_L2 = (short)e.CurrentValue;
                                    break;
                                }
                            case "MaterialCode":
                                {
                                    _08_MaterialCode_L2 = e.CurrentValue.ToString();
                                    /**
                                     * 记录到数据库
                                     */
                                    PassInformationEntity entity = new PassInformationEntity();
                                    entity.ProductionId = _08_MaterialCode_L2;
                                    entity.DeviceCode = "LoadCar02";
                                    entity.Program = "null";
                                    entity.ActionMode = 1;
                                    Task.Run(() => SavePassInformation(entity));
                                    break;
                                }
                        }
                        break;
                    }
                case "NgCar":
                    {
                        switch (e.PropertyName)
                        {
                            case "AtStation":
                                {
                                    _08_AtStation_NG = (bool)e.CurrentValue;
                                    break;
                                }
                            case "Full":
                                {
                                    _08_Full_NG = (bool)e.CurrentValue;
                                    break;
                                }
                            case "WorkpieceNum":
                                {
                                    _08_WorkpieceNum_NG = (short)e.CurrentValue;
                                    break;
                                }
                            case "MaterialCode1":
                                {
                                    _08_MaterialCode1_NG = e.CurrentValue.ToString();
                                    /**
                                     * 记录到数据库
                                     * tb_passinformation 
                                     */
                                    PassInformationEntity entity = new PassInformationEntity();
                                    entity.ProductionId = _08_MaterialCode1_NG;
                                    entity.DeviceCode = "NgCar";
                                    entity.Program = "null";
                                    entity.ActionMode = 1;
                                    Task.Run(() => SavePassInformation(entity));
                                    /**
                                     * 记录最终结果
                                     * 0:未开始  1：加工中  2：加工完成 3:返修中 4：加工失败
                                     */
                                    ProductionEntity productionEntity = new ProductionEntity();
                                    productionEntity.ProductionId = _08_MaterialCode1_NG;
                                    productionEntity.ProductionResult = 4;
                                    productionEntity.UpdateTime = DateTimeOffset.Now;
                                    Task.Run(() => SaveProduction(productionEntity));
                                    break;
                                }
                            case "Reason1":
                                {
                                    _08_Reason1_NG = (short)e.CurrentValue;
                                    /**
                                     * 记录到数据库
                                     */
                                    break;
                                }
                            case "MaterialCode2":
                                {
                                    _08_MaterialCode2_NG = e.CurrentValue.ToString();
                                    /**
                                     * 记录到数据库
                                     * tb_passinformation 
                                     */
                                    PassInformationEntity entity = new PassInformationEntity();
                                    entity.ProductionId = _08_MaterialCode2_NG;
                                    entity.DeviceCode = "NgCar";
                                    entity.Program = "null";
                                    entity.ActionMode = 1;
                                    Task.Run(() => SavePassInformation(entity));
                                    /**
                                     * 记录最终结果
                                     * 0:未开始  1：加工中  2：加工完成 3:返修中 4：加工失败
                                     */
                                    ProductionEntity productionEntity = new ProductionEntity();
                                    productionEntity.ProductionId = _08_MaterialCode2_NG;
                                    productionEntity.ProductionResult = 4;
                                    productionEntity.UpdateTime = DateTimeOffset.Now;
                                    Task.Run(() => SaveProduction(productionEntity));
                                    break;
                                }
                            case "Reason2":
                                {
                                    _08_Reason2_NG = (short)e.CurrentValue;
                                    /**
                                     * 记录到数据库
                                     */
                                    break;
                                }
                            case "MaterialCode3":
                                {
                                    _08_MaterialCode3_NG = e.CurrentValue.ToString();
                                    /**
                                     * 记录到数据库
                                     * tb_passinformation 
                                     */
                                    PassInformationEntity entity = new PassInformationEntity();
                                    entity.ProductionId = _08_MaterialCode3_NG;
                                    entity.DeviceCode = "NgCar";
                                    entity.Program = "null";
                                    entity.ActionMode = 1;
                                    Task.Run(() => SavePassInformation(entity));
                                    /**
                                     * 记录最终结果
                                     * 0:未开始  1：加工中  2：加工完成 3:返修中 4：加工失败
                                     */
                                    ProductionEntity productionEntity = new ProductionEntity();
                                    productionEntity.ProductionId = _08_MaterialCode3_NG;
                                    productionEntity.ProductionResult = 4;
                                    productionEntity.UpdateTime = DateTimeOffset.Now;
                                    Task.Run(() => SaveProduction(productionEntity));
                                    break;
                                }
                            case "Reason3":
                                {
                                    _08_Reason3_NG = (short)e.CurrentValue;
                                    /**
                                     * 记录到数据库
                                     */
                                    break;
                                }
                            case "MaterialCode4":
                                {
                                    _08_MaterialCode4_NG = e.CurrentValue.ToString();
                                    /**
                                     * 记录到数据库
                                     * tb_passinformation 
                                     */
                                    PassInformationEntity entity = new PassInformationEntity();
                                    entity.ProductionId = _08_MaterialCode4_NG;
                                    entity.DeviceCode = "NgCar";
                                    entity.Program = "null";
                                    entity.ActionMode = 1;
                                    Task.Run(() => SavePassInformation(entity));
                                    /**
                                     * 记录最终结果
                                     * 0:未开始  1：加工中  2：加工完成 3:返修中 4：加工失败
                                     */
                                    ProductionEntity productionEntity = new ProductionEntity();
                                    productionEntity.ProductionId = _08_MaterialCode4_NG;
                                    productionEntity.ProductionResult = 4;
                                    productionEntity.UpdateTime = DateTimeOffset.Now;
                                    Task.Run(() => SaveProduction(productionEntity));
                                    break;
                                }
                            case "Reason4":
                                {
                                    _08_Reason4_NG = (short)e.CurrentValue;
                                    /**
                                     * 记录到数据库
                                     */
                                    break;
                                }
                        }
                        break;
                    }
                case "Scanner":
                    {
                        switch (e.PropertyName)
                        {
                            case "StartScanCodeStatus":
                                {
                                    _13_StartScanCodeStatus = (bool)e.CurrentValue;
                                    break;
                                }
                            case "AgainStatus":
                                {
                                    _13_AgainStatus = (bool)e.CurrentValue;
                                    break;
                                }
                            case "PassStatus":
                                {
                                    _13_PassStatus = (bool)e.CurrentValue;
                                    break;
                                }
                            case "ScanCodeBypassStatus":
                                {
                                    _13_ScanCodeBypassStatus = (bool)e.CurrentValue;
                                    break;
                                }
                            case "ScanCodeCom":
                                {
                                    _13_ScanCodeCom = (bool)e.CurrentValue;
                                    break;
                                }
                            case "ScanCodeContent":
                                {
                                    _13_ScanCodeContent = (string)e.CurrentValue;
                                    break;
                                }
                            case "ScanCodeContent_Enter":
                                {
                                    _13_ScanCodeContent_Enter = (string)e.CurrentValue;
                                    break;
                                }
                            case "AutoPass":
                                {
                                    _13_AutoPass = (bool)e.CurrentValue;
                                    break;
                                }
                            case "AutoPassStatus":
                                {
                                    _13_AutoPassStatus = (bool)e.CurrentValue;
                                    break;
                                }
                            case "AutoPassContent":
                                {
                                    _13_AutoPassContent = (string)e.CurrentValue;
                                    break;
                                }
                        }
                        break;
                    }
                case "LaserMark":
                    {
                        switch (e.PropertyName)
                        {
                            case "InitStatus":
                                {
                                    _06_InitStatus = (bool)e.CurrentValue;
                                    break;
                                }
                            case "StartMarkStatus":
                                {
                                    _06_StartMarkStatus = (bool)e.CurrentValue;
                                    break;
                                }
                            case "CodeBypassStatus":
                                {
                                    _06_CodeBypassStatus = (bool)e.CurrentValue;
                                    break;
                                }
                            case "EMO":
                                {
                                    _06_EMO = (bool)e.CurrentValue;
                                    break;
                                }
                            case "Ready":
                                {
                                    _06_Ready = (bool)e.CurrentValue;
                                    break;
                                }
                            case "End":
                                {
                                    _06_End = (bool)e.CurrentValue;
                                    break;
                                }
                            case "HasWorkpiece":
                                {
                                    _06_HasWorkpiece = (bool)e.CurrentValue;
                                    break;
                                }
                            case "Com":
                                {
                                    _06_Com = (bool)e.CurrentValue;
                                    break;
                                }
                            case "InitSuccess":
                                {
                                    _06_InitSuccess = (bool)e.CurrentValue;
                                    break;
                                }
                            case "MarkComplete":
                                {
                                    _06_MarkComplete = (bool)e.CurrentValue;
                                    break;
                                }
                            case "WorkpieceSource":
                                {
                                    _06_WorkpieceSource = (short)e.CurrentValue;
                                    break;
                                }
                            case "MarkContent_Enter":
                                {
                                    _06_MarkContent_Enter = (string)e.CurrentValue;
                                    break;
                                }
                            case "Result":
                                {
                                    _06_Result = e.CurrentValue.ToString();
                                    break;
                                }
                            case "MaterialCode":
                                {
                                    _06_MaterialCode = e.CurrentValue.ToString();
                                    /**
                                     * 记录到数据库
                                     * tb_passinformation
                                     */
                                    PassInformationEntity entity = new PassInformationEntity();
                                    entity.ProductionId = _06_MaterialCode;
                                    entity.DeviceCode = "LaserMark";
                                    entity.ActionMode = 1;
                                    entity.Program = "null";
                                    Task.Run(() => SavePassInformation(entity));
                                    break;
                                }
                            case "ValAct":
                                {
                                    _06_ValAct = (bool)e.CurrentValue;
                                    if (_06_ValAct)
                                    {
                                        LaserMarkContentEntity entity = new LaserMarkContentEntity();
                                        entity.Result = _06_Result;
                                        entity.MaterialCode = _06_MaterialCode;
                                        entity.OccurTime = DateTimeOffset.Now;
                                        Task.Run(() => SaveLaserMarkContent(entity));
                                    }
                                    break;
                                }
                            case "PriEquStaW":
                                {
                                    _06_PriEquStaW = (BitArray)e.CurrentValue;
                                    /**
                                     * 记录到数据库
                                     * tb_deviceStatus
                                     */
                                    DeviceStatusEntity entity = new DeviceStatusEntity();
                                    entity.DeviceCode = "LaserMark";
                                    entity.StatusCode = LinePlantService.BitArrayToInt(_06_PriEquStaW);
                                    entity.StatusDescription = "激光打标机设备状态";
                                    entity.OPType = 1;
                                    Task.Run(() => SaveDeviceStatus(entity));
                                    break;
                                }
                            case "PriEquProStaW":
                                {
                                    _06_PriEquProStaW = (BitArray)e.CurrentValue;
                                    break;
                                }
                            case "PriEquAlarmW_1":
                                {
                                    _06_PriEquAlarmW_1 = (BitArray)e.CurrentValue;
                                    /**
                                     * 记录到数据库
                                     * tb_deviceAlarm
                                     */
                                    DeviceAlarmEntity entity = new DeviceAlarmEntity();
                                    entity.DeviceCode = "LaserMark";
                                    entity.AlarmCode = LinePlantService.BitArrayToInt(_06_PriEquAlarmW_1);
                                    entity.AlarmText = "激光打标报警字1";
                                    entity.AlarmType = 0;
                                    entity.OPType = 1;
                                    Task.Run(() => SaveDeviceAlarm(entity));
                                    break;
                                }
                            case "PriEquAlarmW_2":
                                {
                                    _06_PriEquAlarmW_2 = (BitArray)e.CurrentValue;
                                    /**
                                     * 记录到数据库
                                     * tb_deviceAlram
                                     */
                                    DeviceAlarmEntity entity = new DeviceAlarmEntity();
                                    entity.DeviceCode = "LaserMark";
                                    entity.AlarmCode = LinePlantService.BitArrayToInt(_06_PriEquAlarmW_2);
                                    entity.AlarmText = "激光打标报警字2";
                                    entity.AlarmType = 0;
                                    entity.OPType = 1;
                                    Task.Run(() => SaveDeviceAlarm(entity));
                                    break;
                                }
                            case "PriEquStartEquTime":
                                {
                                    _06_PriEquStartEquTime = (DateTimeOffset)e.CurrentValue;
                                    break;
                                }
                            case "PriEquRunningTime":
                                {
                                    _06_PriEquRunningTime = (double)e.CurrentValue;
                                    break;
                                }
                            case "DataPatternError":
                                {
                                    _06_DataPatternError = (bool)e.CurrentValue;
                                    break;
                                }
                            case "InitFailed":
                                {
                                    _06_InitFailed = (bool)e.CurrentValue;
                                    break;
                                }
                            case "MarkFailed":
                                {
                                    _06_MarkFailed = (bool)e.CurrentValue;
                                    break;
                                }
                        }
                        break;
                    }
                case "Manipulator":
                    {
                        switch (e.PropertyName)
                        {
                            case "RestartStatus":
                                {
                                    _09_RestartStatus = (bool)e.CurrentValue;
                                    break;
                                }
                            case "EMO":
                                {
                                    _09_EMO = (bool)e.CurrentValue;
                                    break;
                                }
                            case "Ready":
                                {
                                    _09_Ready = (bool)e.CurrentValue;
                                    break;
                                }
                            case "HasWorkpiece":
                                {
                                    _09_HasWorkpiece = (bool)e.CurrentValue;
                                    break;
                                }
                            case "WorkpieceSource":
                                {
                                    _09_WorkpieceSource = (short)e.CurrentValue;
                                    break;
                                }
                            case "Grab01":
                                {
                                    _09_Grab01 = (short)e.CurrentValue;
                                    break;
                                }
                            case "Grab02":
                                {
                                    _09_Grab02 = (short)e.CurrentValue;
                                    break;
                                }
                            case "Put01":
                                {
                                    _09_Put01 = (short)e.CurrentValue;
                                    break;
                                }
                            case "Put02":
                                {
                                    _09_Put02 = (short)e.CurrentValue;
                                    break;
                                }
                            case "Position":
                                {
                                    _09_Position = (short)e.CurrentValue;
                                    break;
                                }
                            case "MStatus":
                                {
                                    _09_MStatus = (BitArray)e.CurrentValue;
                                    /**
                                     * TODO 记录到数据库
                                     */
                                    break;
                                }
                            case "MAlarm1":
                                {
                                    _09_MAlarm1 = (BitArray)e.CurrentValue;
                                    /**
                                     * TODO 记录到数据库
                                     */
                                    break;
                                }
                            case "MAlarm2":
                                {
                                    _09_MAlarm2 = (BitArray)e.CurrentValue;
                                    /**
                                     * TODO记录到数据库
                                     */
                                    break;
                                }
                            case "MaterialCode_G1":
                                {
                                    _09_MaterialCode_G1 = e.CurrentValue.ToString();
                                    /**
                                     * 记录到数据库
                                     * tb_passInfomation表，机器人抓手1抓取操作
                                     */
                                    PassInformationEntity entity = new PassInformationEntity();
                                    entity.ProductionId = _09_MaterialCode_G1;
                                    entity.DeviceCode = "Manipulator";
                                    entity.Program = "null";
                                    entity.ActionMode = 1;
                                    Task.Run(() => SavePassInformation(entity));
                                    break;
                                }
                            case "MaterialCode_G2":
                                {
                                    _09_MaterialCode_G2 = e.CurrentValue.ToString();
                                    /**
                                     * 记录到数据库
                                     * tb_passInfomation表，机器人抓手2抓取操作
                                     */
                                    PassInformationEntity entity = new PassInformationEntity();
                                    entity.ProductionId = _09_MaterialCode_G2;
                                    entity.DeviceCode = "Manipulator";
                                    entity.Program = "null";
                                    entity.ActionMode = 1;
                                    Task.Run(() => SavePassInformation(entity));
                                    break;
                                }
                            case "RbStartEquTime":
                                {
                                    _09_RbStartEquTime = (DateTimeOffset)e.CurrentValue;
                                    break;
                                }
                            case "HasAlarm":
                                {
                                    _09_HasAlarm = (bool)e.CurrentValue;
                                    break;
                                }
                            case "AtAuto":
                                {
                                    _09_AtAuto = (bool)e.CurrentValue;
                                    break;
                                }
                            case "MaunalT1":
                                {
                                    _09_MaunalT1 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "ManualT2":
                                {
                                    _09_ManualT2 = (bool)e.CurrentValue;
                                    break;
                                }
                            case "AtInitPosition":
                                {
                                    _09_AtInitPosition = (bool)e.CurrentValue;
                                    break;
                                }
                        }
                        break;
                    }
                case "Lathe01":
                    {
                        switch (e.PropertyName)
                        {
                            case "CncStatus":
                                {
                                    _05_CncStatus_1 = (int)e.CurrentValue;
                                    // 记录机床状态到数据库
                                    DeviceStatusEntity statusEntity = new DeviceStatusEntity
                                    {
                                        DeviceCode = e.DeviceEntity.DeviceCode,
                                        StatusCode = _05_CncStatus_1,
                                        StatusDescription = "",
                                        OPType = 1,
                                        OccurTime = DateTimeOffset.Now,
                                    };
                                    Task.Run(() => SaveDeviceStatus(statusEntity));
                                    break;
                                }

                            case "CncOpMode":
                                {
                                    _05_CncOpMode_1 = (int)e.CurrentValue;
                                    break;
                                }
                            case "ProgramName":
                                {
                                    _05_ProgramName_1 = e.CurrentValue.ToString();
                                    break;
                                }

                            case "NcuBootTime":
                                {
                                    _05_NcuBootTime_1 = (int)e.CurrentValue;
                                    break;
                                }
                            case "NcuOperationTime":
                                {
                                    _05_NcuOperationTime_1 = (double)e.CurrentValue;
                                    break;
                                }

                            case "NcuCycleTime":
                                {
                                    _05_NcuCycleTime_1 = (double)e.CurrentValue;
                                    break;
                                }

                            case "ActToolName":
                                {
                                    _05_ActToolName_1 = (string)e.CurrentValue;
                                    break;
                                }

                            case "ActDNumber":
                                {
                                    _05_ActDNumber_1 = (int)e.CurrentValue;
                                    break;
                                }

                            case "ActToolBasePosX":
                                {
                                    _05_ActToolBasePosX_1 = (double)e.CurrentValue;
                                    break;
                                }

                            case "ActToolBasePosZ":
                                {
                                    _05_ActToolBasePosZ_1 = (double)e.CurrentValue;
                                    break;
                                }

                            case "SpindleSetSpeed":
                                {
                                    _05_SpindleSetSpeed_1 = (double)e.CurrentValue;
                                    break;
                                }

                            case "SpindleActSpeed":
                                {
                                    _05_SpindleActSpeed_1 = (double)e.CurrentValue;
                                    break;
                                }

                            case "SpindleSetFeedRate":
                                {
                                    _05_SpindleSetFeedRate_1 = (double)e.CurrentValue;
                                    break;
                                }

                            case "SpindleActFeedRate":
                                {
                                    _05_SpindleActFeedRate_1 = (double)e.CurrentValue;
                                    break;
                                }

                            case "SpindleSpeedOverRate":
                                {
                                    _05_SpindleSpeedOverRate_1 = (double)e.CurrentValue;
                                    break;
                                }

                            case "CutSpeedOverRate":
                                {
                                    _05_CutSpeedOverRate_1 = (double)e.CurrentValue;
                                    break;
                                }

                            case "SpindleLoad":
                                {
                                    _05_SpindleLoad_1 = (double)e.CurrentValue;
                                    break;
                                }
                            case "FineLathe05ProcessData":
                                {
                                    _05_FineLathe05ProcessData_1 = (FineLathe05ProcessData)e.CurrentValue;
                                    break;
                                }
                            case "MaterialCode":
                                {
                                    _05_MaterialCode_1 = e.CurrentValue.ToString();
                                    /**
                                     * 记录到数据库
                                     */
                                    PassInformationEntity entity = new PassInformationEntity();
                                    entity.ProductionId = _05_MaterialCode_1;
                                    entity.DeviceCode = "Lathe01";
                                    entity.Program = "null";
                                    entity.ActionMode = 1;
                                    Task.Run(() => SavePassInformation(entity));
                                    break;
                                }
                        }
                        break;
                    }
                case "Lathe02":
                    {
                        switch (e.PropertyName)
                        {
                            case "CncStatus":
                                {
                                    _05_CncStatus_2 = (int)e.CurrentValue;
                                    // 记录机床状态到数据库
                                    DeviceStatusEntity statusEntity = new DeviceStatusEntity
                                    {
                                        DeviceCode = e.DeviceEntity.DeviceCode,
                                        StatusCode = _05_CncStatus_2,
                                        StatusDescription = "",
                                        OPType = 1,
                                        OccurTime = DateTimeOffset.Now,
                                    };
                                    Task.Run(() => SaveDeviceStatus(statusEntity));
                                    break;
                                }

                            case "CncOpMode":
                                {
                                    _05_CncOpMode_2 = (int)e.CurrentValue;
                                    break;
                                }
                            case "ProgramName":
                                {
                                    _05_ProgramName_2 = e.CurrentValue.ToString();
                                    break;
                                }

                            case "NcuBootTime":
                                {
                                    _05_NcuBootTime_2 = (int)e.CurrentValue;
                                    break;
                                }
                            case "NcuOperationTime":
                                {
                                    _05_NcuOperationTime_2 = (double)e.CurrentValue;
                                    break;
                                }

                            case "NcuCycleTime":
                                {
                                    _05_NcuCycleTime_2 = (double)e.CurrentValue;
                                    break;
                                }

                            case "ActToolName":
                                {
                                    _05_ActToolName_2 = (string)e.CurrentValue;
                                    break;
                                }

                            case "ActDNumber":
                                {
                                    _05_ActDNumber_2 = (int)e.CurrentValue;
                                    break;
                                }

                            case "ActToolBasePosX":
                                {
                                    _05_ActToolBasePosX_2 = (double)e.CurrentValue;
                                    break;
                                }

                            case "ActToolBasePosZ":
                                {
                                    _05_ActToolBasePosZ_2 = (double)e.CurrentValue;
                                    break;
                                }

                            case "SpindleSetSpeed":
                                {
                                    _05_SpindleSetSpeed_2 = (double)e.CurrentValue;
                                    break;
                                }

                            case "SpindleActSpeed":
                                {
                                    _05_SpindleActSpeed_2 = (double)e.CurrentValue;
                                    break;
                                }

                            case "SpindleSetFeedRate":
                                {
                                    _05_SpindleSetFeedRate_2 = (double)e.CurrentValue;
                                    break;
                                }

                            case "SpindleActFeedRate":
                                {
                                    _05_SpindleActFeedRate_2 = (double)e.CurrentValue;
                                    break;
                                }

                            case "SpindleSpeedOverRate":
                                {
                                    _05_SpindleSpeedOverRate_2 = (double)e.CurrentValue;
                                    break;
                                }

                            case "CutSpeedOverRate":
                                {
                                    _05_CutSpeedOverRate_2 = (double)e.CurrentValue;
                                    break;
                                }

                            case "SpindleLoad":
                                {
                                    _05_SpindleLoad_2 = (double)e.CurrentValue;
                                    break;
                                }
                            case "FineLathe05ProcessData":
                                {
                                    _05_FineLathe05ProcessData_2 = (FineLathe05ProcessData)e.CurrentValue;
                                    break;
                                }
                            case "MaterialCode":
                                {
                                    _05_MaterialCode_2 = e.CurrentValue.ToString();
                                    /**
                                     * 记录到数据库
                                     */
                                    PassInformationEntity entity = new PassInformationEntity();
                                    entity.ProductionId = _05_MaterialCode_2;
                                    entity.DeviceCode = "Lathe02";
                                    entity.Program = "null";
                                    entity.ActionMode = 1;
                                    Task.Run(() => SavePassInformation(entity));
                                    break;
                                }
                        }
                        break;
                    }
                case "Lathe03":
                    {
                        switch (e.PropertyName)
                        {
                            case "CncStatus":
                                {
                                    _05_CncStatus_3 = (int)e.CurrentValue;
                                    // 记录机床状态到数据库
                                    DeviceStatusEntity statusEntity = new DeviceStatusEntity
                                    {
                                        DeviceCode = e.DeviceEntity.DeviceCode,
                                        StatusCode = _05_CncStatus_3,
                                        StatusDescription = "",
                                        OPType = 1,
                                        OccurTime = DateTimeOffset.Now,
                                    };
                                    Task.Run(() => SaveDeviceStatus(statusEntity));
                                    break;
                                }

                            case "CncOpMode":
                                {
                                    _05_CncOpMode_3 = (int)e.CurrentValue;
                                    break;
                                }
                            case "ProgramName":
                                {
                                    _05_ProgramName_3 = e.CurrentValue.ToString();
                                    break;
                                }

                            case "NcuBootTime":
                                {
                                    _05_NcuBootTime_3 = (int)e.CurrentValue;
                                    break;
                                }
                            case "NcuOperationTime":
                                {
                                    _05_NcuOperationTime_3 = (double)e.CurrentValue;
                                    break;
                                }

                            case "NcuCycleTime":
                                {
                                    _05_NcuCycleTime_3 = (double)e.CurrentValue;
                                    break;
                                }

                            case "ActToolName":
                                {
                                    _05_ActToolName_3 = (string)e.CurrentValue;
                                    break;
                                }

                            case "ActDNumber":
                                {
                                    _05_ActDNumber_3 = (int)e.CurrentValue;
                                    break;
                                }

                            case "ActToolBasePosX":
                                {
                                    _05_ActToolBasePosX_3 = (double)e.CurrentValue;
                                    break;
                                }

                            case "ActToolBasePosZ":
                                {
                                    _05_ActToolBasePosZ_3 = (double)e.CurrentValue;
                                    break;
                                }

                            case "SpindleSetSpeed":
                                {
                                    _05_SpindleSetSpeed_3 = (double)e.CurrentValue;
                                    break;
                                }

                            case "SpindleActSpeed":
                                {
                                    _05_SpindleActSpeed_3 = (double)e.CurrentValue;
                                    break;
                                }

                            case "SpindleSetFeedRate":
                                {
                                    _05_SpindleSetFeedRate_3 = (double)e.CurrentValue;
                                    break;
                                }

                            case "SpindleActFeedRate":
                                {
                                    _05_SpindleActFeedRate_3 = (double)e.CurrentValue;
                                    break;
                                }

                            case "SpindleSpeedOverRate":
                                {
                                    _05_SpindleSpeedOverRate_3 = (double)e.CurrentValue;
                                    break;
                                }

                            case "CutSpeedOverRate":
                                {
                                    _05_CutSpeedOverRate_3 = (double)e.CurrentValue;
                                    break;
                                }

                            case "SpindleLoad":
                                {
                                    _05_SpindleLoad_3 = (double)e.CurrentValue;
                                    break;
                                }
                            case "FineLathe05ProcessData":
                                {
                                    _05_FineLathe05ProcessData_3 = (FineLathe05ProcessData)e.CurrentValue;
                                    break;
                                }
                            case "MaterialCode":
                                {
                                    _05_MaterialCode_3 = e.CurrentValue.ToString();
                                    /**
                                     * 记录到数据库
                                     */
                                    PassInformationEntity entity = new PassInformationEntity();
                                    entity.ProductionId = _05_MaterialCode_3;
                                    entity.DeviceCode = "Lathe03";
                                    entity.Program = "null";
                                    entity.ActionMode = 1;
                                    Task.Run(() => SavePassInformation(entity));
                                    break;
                                }
                        }
                        break;
                    }
                case "ThreeCoordinatesMeasure":
                    {
                        switch (e.PropertyName)
                        {
                            case "BypassStatus":
                                {
                                    _11_BypassStatus = (bool)e.CurrentValue;
                                    break;
                                }
                            case "Ready":
                                {
                                    _11_Ready = (bool)e.CurrentValue;
                                    break;
                                }
                            case "End":
                                {
                                    _11_End = (bool)e.CurrentValue;
                                    break;
                                }
                            case "HasWorkpiece":
                                {
                                    _11_HasWorkpiece = (bool)e.CurrentValue;
                                    break;
                                }
                            case "WorkpieceSource":
                                {
                                    _11_WorkpieceSource = (short)e.CurrentValue;
                                    break;
                                }
                            case "MCode":
                                {
                                    _11_MCode = (string)e.CurrentValue;
                                    /**
                                     * 记录到数据库
                                     * tb_passInfomation
                                     */
                                    PassInformationEntity entity = new PassInformationEntity();
                                    entity.ProductionId = _11_MCode;
                                    entity.DeviceCode = "ThreeCoordinatesMeasure";
                                    entity.Program = "null";
                                    entity.ActionMode = 1;
                                    Task.Run(() => SavePassInformation(entity));
                                    break;
                                }
                            case "HandleMachine2":
                                {
                                    bool result = (bool)e.CurrentValue;
                                    if (result)
                                    {
                                        _11_HandleMachine = "数控车床2";
                                    }                                   
                                    break;
                                }
                            case "HandleMachine3":
                                {
                                    bool result = (bool)e.CurrentValue;
                                    if (result)
                                    {
                                        _11_HandleMachine = "数控车床3";
                                    }
                                    
                                    break;
                                }
                            case "ProductBatch":
                                {
                                    _11_ProductBatch = (string)e.CurrentValue;
                                    break;
                                }
                            case "GetResult":
                                {
                                    _11_GetResult = (string)e.CurrentValue;
                                    if (_11_GetResult.Split("|")[0]=="True")
                                    {
                                        string[] times = _11_GetResult.Split("|")[1].Split(" ")[0].Split("/");
                                        int year = int.Parse(times[0]);
                                        int month = int.Parse(times[1]);
                                        int day = int.Parse(times[2]);
                                        string[] _times = _11_GetResult.Split("|")[1].Split(" ")[1].Split(":");
                                        int hour = int.Parse(_times[0]);
                                        int minnals = int.Parse(_times[1]);
                                        int seconds = int.Parse(_times[2]);
                                        DateTimeOffset occurTime = new DateTimeOffset(year, month, day, hour, minnals, seconds,new TimeSpan(8,0,0));
                                        occurTime = occurTime.AddHours(8);
                                        // 读取三坐标的值
                                        List<string> result = GetThreeCoordinatesResult();
                                        /**
                                         * 记录到数据库
                                         * tb_threeCoordinatesMeasureRecord
                                         */
                                        ThreeCoordinatesMeasureRecordEntity entity = new ThreeCoordinatesMeasureRecordEntity();
                                        StringBuilder str = new StringBuilder();
                                        string _result = "合格";
                                        for (int i = 0; i < result.Count; i++)
                                        {
                                            if (result[i] != null && result[i].Equals("") != true)
                                            {
                                                if ((i + 1) != result.Count)
                                                {
                                                    str.Append(result[i] + "/");
                                                }
                                                else
                                                {
                                                    str.Append(result[i]);
                                                }
                                                if (result[i].IndexOf(":406") != -1)
                                                {
                                                    _result = "不合格";
                                                }
                                            }
                                        }
                                        entity.Result = str.ToString();
                                        int test = entity.Result.Length;    
                                        entity.OccurTime = occurTime;
                                        entity.MCode = _11_MCode;
                                        entity.HandleMachine = "数控机床1   "+_11_HandleMachine;                                        
                                        Task.Run(() => SaveThreeCoordinatesMeasureRecord(entity));
                                        /**
                                         * 记录到数据库
                                         * tb_threeCoordinatesMeasureMoudle
                                         */
                                        ThreeCoordinatesMeasureMoudleEntity entity1 = new ThreeCoordinatesMeasureMoudleEntity();
                                        entity1.ProductBatch = _11_ProductBatch;
                                        entity1.MaterialCode = _11_MCode;
                                        entity1.Param_1 = result[0];
                                        entity1.Param_2 = result[1];
                                        entity1.Param_3 = result[2];
                                        entity1.Param_4 = result[3];
                                        entity1.Param_5 = result[4];
                                        entity1.Param_6 = result[5];
                                        entity1.Param_7 = result[6];
                                        entity1.Param_8 = result[7];
                                        entity1.Param_9 = result[8];
                                        entity1.Param_10 = result[9];
                                        entity1.Param_11 = result[10];
                                        entity1.Param_12 = result[11];
                                        entity1.Param_13 = result[12];
                                        entity1.Param_14 = result[13];
                                        entity1.Param_15 = result[14];
                                        entity1.Param_16 = result[15];
                                        entity1.Param_17 = result[16];
                                        entity1.Param_18 = result[17];
                                        entity1.Param_19 = result[18];
                                        entity1.Param_20 = result[19];
                                        entity1.Param_21 = result[20];
                                        entity1.Result = _result;
                                        Task.Run(() => SaveThreeCoordinatesMeasureMoudle(entity1));
                                        /**
                                         * 添加记录到MES模板Excel文件中
                                         */
                                        Task.Run(() => recordMesExcel(entity1));
                                    }
                                    break;
                                }
                            case "ThreeEquStaW":
                                {
                                    _11_ThreeEquStaW = (BitArray)e.CurrentValue;
                                    /**
                                     * 记录到数据库
                                     * tb_deviceStatus
                                     */
                                    DeviceStatusEntity entity = new DeviceStatusEntity();
                                    entity.DeviceCode = "ThreeCoordinatesMeasure";
                                    entity.StatusCode = LinePlantService.BitArrayToInt(_11_ThreeEquStaW);
                                    entity.StatusDescription = "三坐标状态";
                                    entity.OPType = 1;
                                    entity.OccurTime = DateTimeOffset.Now;
                                    Task.Run(() => SaveDeviceStatus(entity));
                                    break;
                                }
                            case "ThreeEquProStaW":
                                {
                                    _11_ThreeEquProStaW = (BitArray)e.CurrentValue;
                                    break;
                                }
                            case "ThreeEquAlarmW_1":
                                {
                                    _11_ThreeEquAlarmW_1 = (BitArray)e.CurrentValue;
                                    /**
                                     * 记录到数据库
                                     * tb_deviceAlarm
                                     */
                                    DeviceAlarmEntity entity = new DeviceAlarmEntity();
                                    entity.DeviceCode = "ThreeCoordinatesMeasure";
                                    entity.AlarmCode = LinePlantService.BitArrayToInt(_11_ThreeEquAlarmW_1);
                                    entity.AlarmText = "三坐标报警";
                                    entity.AlarmType = 0;
                                    entity.OPType = 1;
                                    Task.Run(() => SaveDeviceAlarm(entity));
                                    break;
                                }
                            case "ThreeEquAlarmW_2":
                                {
                                    _11_ThreeEquAlarmW_2 = (BitArray)e.CurrentValue;
                                    /**
                                     * 记录到数据库
                                     * tb_deviceAlarm
                                     */
                                    DeviceAlarmEntity entity = new DeviceAlarmEntity();
                                    entity.DeviceCode = "ThreeCoordinatesMeasure";
                                    entity.AlarmCode = LinePlantService.BitArrayToInt(_11_ThreeEquAlarmW_2);
                                    entity.AlarmText = "三坐标报警";
                                    entity.AlarmType = 0;
                                    entity.OPType = 1;
                                    Task.Run(() => SaveDeviceAlarm(entity));
                                    break;
                                }
                            case "ThreeEquActProNo":
                                {
                                    _11_ThreeEquActProNo = (string)e.CurrentValue;
                                    break;
                                }
                            case "ThreeEquMaterialCode":
                                {
                                    _11_ThreeEquMaterialCode = (string)e.CurrentValue;
                                    /**
                                     * 记录到数据库
                                     * tb_passInformation
                                     */
                                    PassInformationEntity entity = new PassInformationEntity();
                                    entity.ProductionId = _11_ThreeEquMaterialCode;
                                    entity.DeviceCode = "ThreeCoordinatesMeasure";
                                    entity.Program = _11_ThreeEquActProNo;
                                    entity.ActionMode = 1;
                                    Task.Run(() => SavePassInformation(entity));
                                    break;
                                }
                            case "ThreeEquStartEquTime":
                                {
                                    _11_ThreeEquStartEquTime = (DateTimeOffset)e.CurrentValue;
                                    break;
                                }
                            case "ThreeEquRunningTime":
                                {
                                    _11_ThreeEquRunningTime = (double)e.CurrentValue;
                                    break;
                                }
                            case "ThreeResult":
                                {
                                    _11_ThreeResult = (bool)e.CurrentValue;
                                    break;
                                }
                            case "ThreeValRequst":
                                {
                                    _11_ThreeValRequst = (bool)e.CurrentValue;
                                    break;
                                }
                            case "ThreeValAct":
                                {
                                    _11_ThreeValAct = (bool)e.CurrentValue;
                                    break;
                                }
                            case "LoadFileFailed":
                                {
                                    _11_LoadFileFailed = (bool)e.CurrentValue;
                                    break;
                                }
                        }
                        break;
                    }
                case "WashMachine":
                    {
                        switch (e.PropertyName)
                        {
                            case "BypassStatus":
                                {
                                    _01_BypassStatus = (bool)e.CurrentValue;
                                    break;
                                }
                            case "EMO":
                                {
                                    _01_EMO = (bool)e.CurrentValue;
                                    break;
                                }
                            case "Ready":
                                {
                                    _01_Ready = (bool)e.CurrentValue;
                                    break;
                                }
                            case "End":
                                {
                                    _01_End = (bool)e.CurrentValue;
                                    break;
                                }
                            case "WorkpieceSource":
                                {
                                    _01_WorkpieceSource = (short)e.CurrentValue;
                                    break;
                                }
                            case "MCode":
                                {
                                    _01_MCode = (string)e.CurrentValue;
                                    /**
                                     * 记录到数据库
                                     * tb_passInformation
                                     */
                                    PassInformationEntity entity = new PassInformationEntity();
                                    entity.ProductionId = _01_MCode;
                                    entity.DeviceCode = "WashMachine";
                                    entity.Program = "null";
                                    entity.ActionMode = 1;
                                    Task.Run(() => SavePassInformation(entity));
                                    break;
                                }
                            case "MStatus":
                                {
                                    _01_MStatus = (BitArray)e.CurrentValue;
                                    /**
                                     * 记录到数据库
                                     * tb_deviceStatus
                                     */
                                    DeviceStatusEntity entity = new DeviceStatusEntity();
                                    entity.DeviceCode = "WashMachine";
                                    entity.StatusCode = LinePlantService.BitArrayToInt(_01_MStatus);
                                    entity.StatusDescription = "清洗机状态";
                                    entity.OPType = 1;
                                    Task.Run(() => SaveDeviceStatus(entity));
                                    break;
                                }
                            case "MAlarm1":
                                {
                                    _01_MAlarm1 = (BitArray)e.CurrentValue;
                                    /**
                                     * 记录到数据库
                                     * tb_deviceAlarm
                                     */
                                    DeviceAlarmEntity entity = new DeviceAlarmEntity();
                                    entity.DeviceCode = "WashMachine";
                                    entity.AlarmCode = LinePlantService.BitArrayToInt(_01_MAlarm1);
                                    entity.AlarmText = "清洗机报警字1";
                                    entity.AlarmType = 0;
                                    entity.OPType = 1;
                                    Task.Run(() => SaveDeviceAlarm(entity));
                                    break;
                                }
                            case "MAlarm2":
                                {
                                    _01_MAlarm2 = (BitArray)e.CurrentValue;
                                    /**
                                     * 记录到数据库
                                     * tb_deviceAlarm
                                     */
                                    DeviceAlarmEntity entity = new DeviceAlarmEntity();
                                    entity.DeviceCode = "WashMachine";
                                    entity.AlarmCode = LinePlantService.BitArrayToInt(_01_MAlarm2);
                                    entity.AlarmText = "清洗机报警字2";
                                    entity.AlarmType = 0;
                                    entity.OPType = 1;
                                    Task.Run(() => SaveDeviceAlarm(entity));
                                    break;
                                }
                            case "WashTime":
                                {
                                    _01_WashTime = (long)e.CurrentValue;
                                    break;
                                }
                            case "WashSpeed":
                                {
                                    _01_WashSpeed = (double)e.CurrentValue;
                                    break;
                                }
                            case "CleanEquStartEquTime":
                                {
                                    _01_CleanEquStartEquTime = (DateTimeOffset)e.CurrentValue;
                                    break;
                                }
                            case "CleanEquRunningTime":
                                {
                                    _01_CleanEquRunningTime=(double)e.CurrentValue;
                                    break;
                                }
                            case "HasAlarm":
                                {
                                    _01_HasAlarm = (bool)e.CurrentValue;
                                    break;
                                }
                            case "HasError":
                                {
                                    _01_HasError = (bool)e.CurrentValue;
                                    break;
                                }
                        }
                        break;
                    }
                default:
                    {
                        break;
                    }
            }
        }
        #endregion

        #region 获取机床报警信息

        public List<DeviceAlarm> GetDeviceAlarm(string deviceCode)
        {
            List<DeviceAlarm> list = new List<DeviceAlarm>();
            foreach (var device in basicDevices)
            {
                if (device.DeviceEntity.DeviceCode == deviceCode)
                {
                    FineLathe_05 fineLathe_05 = device as FineLathe_05;
                    fineLathe_05.GetDeviceAlarms();
                }
            }
            return null;
        }

        #endregion

        #region 获取刀具信息
        /// <summary>
        /// 获取刀具信息
        /// </summary>
        /// <param name="deviceCode">设备编码</param>
        /// <returns></returns>
        public Object GetToolByDeviceCode(string deviceCode)
        {
            ToolHouseDescription toolHouseDescription = null;
            List<ToolListInfo> toolinfo = null;            
            foreach (var device in basicDevices)
            {
                if (device.DeviceEntity.DeviceCode == deviceCode)
                {
                    FineLathe_05 fineLathe_05 = device as FineLathe_05;
                    toolHouseDescription = fineLathe_05.GetToolHouseInfo();
                    toolinfo = fineLathe_05.GetToolInfo();
                }
            }
            return new { toolHouseDescription = toolHouseDescription, toolinfo = toolinfo };
        }

        public Object GetToolDetail(string deviceCode,int toolIndex)
        {
            ToolEdgeInfo toolEdgeInfo = new ToolEdgeInfo();
            foreach (var device in basicDevices)
            {
                if (device.DeviceEntity.DeviceCode == deviceCode)
                {
                    FineLathe_05 fineLathe_05 = device as FineLathe_05;
                    toolEdgeInfo = fineLathe_05.GetToolEdgeInfo(toolIndex);
                }
            }
            return new { toolEdgeInfo = toolEdgeInfo };
        }

        /// <summary>
        /// 设置刀补
        /// </summary>
        /// <param name="deviceCode">数控机床编号</param>
        /// <param name="toolIndex">刀具号</param>
        /// <param name="offX">X偏移量，null代表不设置</param>
        /// <param name="offZ">Z偏移量，null代表不设置</param>
        /// <param name="offR">R偏移量，null代表不设置</param>
        public void setToolEdge(string deviceCode, int toolIndex, double? offX, double? offZ, double? offR)
        {
            foreach (var device in basicDevices)
            {
                if (device.DeviceEntity.DeviceCode == deviceCode)
                {
                    FineLathe_05 fineLathe_05 = device as FineLathe_05;
                    fineLathe_05.setToolEdge(toolIndex, offX, offZ, offR);
                }
            }
        }
        #endregion

        #region 写入OPC值方法
        public bool WriteValue(string deviceCode,string tag, string value)
        {

            IEnumerable<OpcDataSourceEntity> opcDataSourceEntities;
            bool s = avaliableOpcDeivceDataSources.TryGetValue(deviceCode, out opcDataSourceEntities);
            if(s)
            {
                var dataSource = opcDataSourceEntities.Where(i => i.SourceAddress == tag).FirstOrDefault();
                if(dataSource!=null)
                {
                    return workshopCommunicationService.WriteValue(dataSource.ServerId, tag, value);
                }
                else
                {
                    return false;
                }
            }

            else
            {
                return false;
            }
        }


        public bool WriteValue(OpcDataSourceEntity opcDataSourceEntity, string value)
        {
            return workshopCommunicationService.WriteValue(opcDataSourceEntity.ServerId, opcDataSourceEntity.SourceAddress, value);
        }

        public bool WriteValue<T>(OpcDataSourceEntity opcDataSourceEntity, T value)
        {
            return workshopCommunicationService.WriteValue(opcDataSourceEntity.ServerId, opcDataSourceEntity.SourceAddress, value);
        }

        public bool WriteValue<T>(Guid serverId, string tag, T value)
        {
            return workshopCommunicationService.WriteValue(serverId, tag, value);
        }

        public List<DataValue> ReadValues(OpcDataSourceEntity opcDataSourceEntity, List<string> nodeIds)
        {
            return workshopCommunicationService.ReadValues(opcDataSourceEntity.ServerId, nodeIds);
        }
        #endregion

        #region 数据库操作方法
        private async Task<IEnumerable<DeviceEntity>> SearchAllDevice()
        {
            var reslut = await this.BaseRepository().FindList<DeviceEntity>();
            return reslut;
        }

        private async Task SaveDeviceStatus(DeviceStatusEntity entity)
        {
            DateTimeOffset now = DateTimeOffset.Now;
            if (entity.Id.IsGuidNullOrEmpty())
            {
                entity.Id = Guid.NewGuid();
            }
            entity.OrderBy = 0;
            entity.IsDeleted = false;
            entity.OccurTime = now;
            entity.CreateTime = now;
            entity.UpdateTime = now;
            await this.BaseRepository().Insert(entity);
        }

        private async Task<IEnumerable<OpcServerDescriptionEntity>> SerarchOpcServerById(Guid serverId)
        {
            var result = await this.BaseRepository().FindList<OpcServerDescriptionEntity>(o => o.Id == serverId);
            return result;
        }

        private async Task<IEnumerable<OpcDataSourceEntity>> GetOpcDataSourceByServerIdsAndDeviceCode(IEnumerable<Guid> serverIds, string deviceCode)
        {
            IEnumerable<OpcDataSourceEntity> result = null;
            foreach (var id in serverIds)
            {
                try
                {
                    IEnumerable<OpcDataSourceEntity> _result = await this.BaseRepository().FindList<OpcDataSourceEntity>(o => o.ServerId == id && o.DeviceCode == deviceCode);
                    if (_result.Count() != 0)
                    {
                        result = _result;
                    }
                }
                catch(Exception ex)
                {
                    throw ex;
                }
                
            }
            return result;
        }

        private async Task SaveThreeCoordinatesMeasureRecord(ThreeCoordinatesMeasureRecordEntity entity)
        {
            if (entity.Id.IsGuidNullOrEmpty())
            {
                entity.Id = Guid.NewGuid();
            }
            await this.BaseRepository().Insert(entity);
        }

        public async Task SaveLaserMarkContent(LaserMarkContentEntity entity)
        {
            if (entity.Id.IsGuidNullOrEmpty())
            {
                entity.Id = Guid.NewGuid();
            }
            await this.BaseRepository().Insert(entity);
        }

        /// <summary>
        /// PassInformation接口
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task SavePassInformation(PassInformationEntity entity)
        {
            if (entity.Id.IsGuidNullOrEmpty())
            {
                Guid guid = Guid.NewGuid();
                entity.Id = guid;
            }
            DateTimeOffset now = DateTimeOffset.Now;
            entity.UpdateTime = now;
            await this.BaseRepository().Insert<PassInformationEntity>(entity);
        }

        /// <summary>
        /// DeviceAlarm接口
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task SaveDeviceAlarm(DeviceAlarmEntity entity)
        {
            if (entity.Id.IsGuidNullOrEmpty())
            {
                entity.Id = Guid.NewGuid();
            }
            DateTimeOffset now = DateTimeOffset.Now;
            entity.OccurTime = now;
            entity.OrderBy = 0;
            entity.IsDeleted = false;
            entity.CreateTime = now;
            entity.UpdateTime = now;
            await this.BaseRepository().Insert(entity);
        }

        /// <summary>
        /// 通过ID获取三坐标信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<IEnumerable<ThreeCoordinatesMeasureRecordEntity>> SearchById(Guid id)
        {
            var result = await this.BaseRepository().FindList<ThreeCoordinatesMeasureRecordEntity>(o => o.Id == id);
            return result;
        }

        /// <summary>
        /// 记录ThreeCoordinatesMeasureMoudle
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task SaveThreeCoordinatesMeasureMoudle(ThreeCoordinatesMeasureMoudleEntity entity)
        {
            if (entity.Id.IsGuidNullOrEmpty())
            {
                entity.Id = Guid.NewGuid();
            }
            DateTimeOffset now = DateTimeOffset.Now;
            entity.RecordDate = now;
            await this.BaseRepository().Insert<ThreeCoordinatesMeasureMoudleEntity>(entity);
        }

        /// <summary>
        /// 报错EXCEL下一行数记录
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task SaveExcelRowPositionRecord(ExcelRowPositionRecordEntity entity)
        {
            if (entity.Id.IsGuidNullOrEmpty())
            {
                entity.Id = Guid.NewGuid();
            }
            await this.BaseRepository().Insert(entity);
        }

        /// <summary>
        /// 获取EXCEL下一行数记录
        /// </summary>
        /// <param name="productBatch"></param>
        /// <returns></returns>
        public async Task<IEnumerable<ExcelRowPositionRecordEntity>> SearchExcelRowPositionRecordByProductBatch(string productBatch)
        {
            var reslut = await this.BaseRepository().FindList<ExcelRowPositionRecordEntity>(o => o.ProductBatch == productBatch);
            return reslut;
        }

        /// <summary>
        /// 更新EXCEL下一行数记录
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task UpdateExcelRowPositionRecord(ExcelRowPositionRecordEntity entity)
        {
            await this.BaseRepository().Update<ExcelRowPositionRecordEntity>(entity);
        }

        /// <summary>
        /// 保存孔深测量数据
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task SaveProductionHoleDepth(ProductionHoleDepthEntity entity)
        {
            if (entity.Id.IsGuidNullOrEmpty())
            {
                entity.Id = Guid.NewGuid();
            }
            await this.BaseRepository().Insert(entity);
        }

        /// <summary>
        /// 保存加工结果
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task SaveProduction(ProductionEntity entity)
        {
            if (entity.Id.IsGuidNullOrEmpty())
            {
                entity.Id = Guid.NewGuid();
            }
            await this.BaseRepository().Insert(entity);
        }
        #endregion

        #region 添加记录到MES模板Excel中

        private async void recordMesExcel(ThreeCoordinatesMeasureMoudleEntity entity)
        {
            // 模板文件
            string tempFile = "C:\\Users\\42199\\Desktop\\工作资料\\西北新项目\\整理分析\\待开发功能\\excel模板\\三坐标结果MES模板.xlsx";

            // 模板文件存放地址
            string tempPath = "C:\\Users\\42199\\Desktop\\工作资料\\西北新项目\\整理分析\\待开发功能\\excel模板\\生成目标目录";

            /**
             * 判断该批次的Excel文件存不存在，存在追加数据，不存在新建数据
             */

            string productBatch = entity.ProductBatch;
            string targetFile = tempPath + "\\" + productBatch + ".xlsx";
            if (File.Exists(tempPath))
            {
                /**
                 * 追加数据
                 */

                // 获取数据库记录的追加数据行数
                IEnumerable<ExcelRowPositionRecordEntity> excelRow = await SearchExcelRowPositionRecordByProductBatch(entity.ProductBatch);
                ExcelRowPositionRecordEntity excelRowPosition = excelRow.First();
                int rowPosition = excelRowPosition.Position;

                // 添加数据
                bool result= addExcelData(targetFile, entity, rowPosition);

                if (result)
                {
                    excelRowPosition.Position++;
                    await UpdateExcelRowPositionRecord(excelRowPosition);
                }
            }
            else
            {
                /**
                 * 新建模板填充数据
                 */

                int rowPosition = 9;
                File.Copy(tempPath, targetFile);

                // 添加数据
                bool result = addExcelData(targetFile, entity, rowPosition);

                if (result)
                {
                    ExcelRowPositionRecordEntity excelRowPosition = new ExcelRowPositionRecordEntity();
                    excelRowPosition.ProductBatch = entity.ProductBatch;
                    excelRowPosition.Position = rowPosition + 1;
                    await SaveExcelRowPositionRecord(excelRowPosition);
                }
            }
        }

        public bool addExcelData(string filepath, ThreeCoordinatesMeasureMoudleEntity entity,int rowPosition)
        {
            bool result = true;
            try
            {
                XLWorkbook xLWorkbook = new XLWorkbook(filepath);
                IXLWorksheet worksheet = xLWorkbook.Worksheets.Worksheet("Sheet1");
                // 产品批号
                worksheet.Cell(rowPosition, 1).Value = entity.ProductBatch;
                // 产品编码
                worksheet.Cell(rowPosition, 2).Value = entity.MaterialCode;
                // 项目1
                worksheet.Cell(rowPosition, 3).Value = entity.Param_1;
                // 项目2
                worksheet.Cell(rowPosition, 4).Value = entity.Param_2;
                // 项目3
                worksheet.Cell(rowPosition, 5).Value = entity.Param_3;
                // 项目4
                worksheet.Cell(rowPosition, 6).Value = entity.Param_4;
                // 项目5
                worksheet.Cell(rowPosition, 7).Value = entity.Param_5;
                // 项目6
                worksheet.Cell(rowPosition, 8).Value = entity.Param_6;
                // 项目7
                worksheet.Cell(rowPosition, 9).Value = entity.Param_7;
                // 项目8
                worksheet.Cell(rowPosition, 10).Value = entity.Param_8;
                // 项目9
                worksheet.Cell(rowPosition, 11).Value = entity.Param_9;
                // 项目10
                worksheet.Cell(rowPosition, 12).Value = entity.Param_10;
                // 项目11
                worksheet.Cell(rowPosition, 13).Value = entity.Param_11;
                // 项目12
                worksheet.Cell(rowPosition, 14).Value = entity.Param_12;
                // 项目13
                worksheet.Cell(rowPosition, 15).Value = entity.Param_13;
                // 项目14
                worksheet.Cell(rowPosition, 16).Value = entity.Param_14;
                // 项目15
                worksheet.Cell(rowPosition, 17).Value = entity.Param_15;
                // 项目16
                worksheet.Cell(rowPosition, 18).Value = entity.Param_16;
                // 项目17
                worksheet.Cell(rowPosition, 19).Value = entity.Param_17;
                // 项目18
                worksheet.Cell(rowPosition, 20).Value = entity.Param_18;
                // 项目19
                worksheet.Cell(rowPosition, 21).Value = entity.Param_19;
                // 项目20
                worksheet.Cell(rowPosition, 22).Value = entity.Param_20;
                // 项目21
                worksheet.Cell(rowPosition, 23).Value = entity.Param_21;
                // 结果
                worksheet.Cell(rowPosition, 24).Value = entity.Result;
                using (MemoryStream stream = new MemoryStream())
                {
                    xLWorkbook.SaveAs(filepath);
                }
            }
            catch(Exception ex)
            {
                result = false;
            }
            return result;
        }

        #endregion

        #region 读取三坐标的数据

        public List<string> GetThreeCoordinatesResult()
        {
            List<string> result = new List<string>();
            foreach(var device in basicDevices)
            {
                if(device.DeviceEntity.DeviceCode== "ThreeCoordinatesMeasure")
                {
                    ThreeCoordinatesMeasure_11 threeCoordinatesMeasure_11 = device as ThreeCoordinatesMeasure_11;
                    result = threeCoordinatesMeasure_11.GetThreeCoordinatesResult();
                }
            }
            return result;
        }

        #endregion

        #region 总控PLC数据

        /// <summary>
        /// 订单控制模式 true=远程（启用数据跟踪） false=本地（不跟踪数据）
        /// </summary>
        public bool OrderControlMode { get; set; }

        /// <summary>
        /// 手动模式
        /// </summary>
        public bool ManualStatus { get; set; }

        /// <summary>
        /// 自动模式
        /// </summary>
        public bool AutoStatus { get; set; }

        /// <summary>
        /// 首件模式
        /// </summary>
        public bool FirstpieceStatus { get; set; }

        /// <summary>
        /// 准备模式
        /// </summary>
        public bool AutoReadyStatus { get; set; }

        /// <summary>
        /// 启动模式
        /// </summary>
        public bool AutoRunStatus { get; set; }

        /// <summary>
        /// 停止模式
        /// </summary>
        public bool AutoStopStatus { get; set; }

        /// <summary>
        /// 全线重新开始
        /// </summary>
        public bool AllRestartStatus { get; set; }

        /// <summary>
        /// 运行暂停
        /// </summary>
        public bool SuspendStatus { get; set; }

        public bool BypassStatus_01 { get; set; }

        public bool BypassStatus_02 { get; set; }

        public bool BypassStatus_03 { get; set; }

        public bool EMO_01 { get; set; }

        public bool EMO_02 { get; set; }

        public bool EMO_03 { get; set; }

        public bool Ready_01 { get; set; }

        public bool Ready_02 { get; set; }

        public bool Ready_03 { get; set; }

        public bool End_01 { get; set; }

        public bool End_02 { get; set; }

        public bool End_03 { get; set; }

        public bool HasWorkpiece_01 { get; set; }

        public bool HasWorkpiece_02 { get; set; }

        public bool HasWorkpiece_03 { get; set; }

        /// <summary>
        /// 工件来源
        /// </summary>
        public short WorkpieceSource_01 { get; set; }

        public short WorkpieceSource_02 { get; set; }

        public short WorkpieceSource_03 { get; set; }

        public bool DayOff { get; set; }

        public bool DayOffStatus { get; set; }


        #endregion

        #region 孔深测量

        public bool _02_BypassStatus { get; set; }

        public bool _02_EMO { get; set; }

        public bool _02_Ready { get; set; }

        public bool _02_End { get; set; }

        public bool _02_HasWorkpiece { get; set; }

        public short _02_RealCount { get; set; }

        public short _02_WorkpieceSource { get; set; }

        public short _02_CountSet { get; set; }

        public string _02_MaterialCode { get; set; }

        public double _02_Depth { get; set; }

        public double _02_HoLength { get; set; }

        public bool _02_ValAct { get; set; }

        /// <summary>
        /// 孔深测量设备状态字
        /// </summary>
        public BitArray _02_DMEquStaW { get; set; }

        /// <summary>
        /// 孔深测量程序状态字
        /// </summary>
        public BitArray _02_DMEquProStaW { get; set; }

        /// <summary>
        /// 孔深测量设备报警字1
        /// </summary>
        public BitArray _02_DMEquAlarmW_1 { get; set; }

        /// <summary>
        /// 孔深测量设备报警字2
        /// </summary>
        public BitArray _02_DMEquAlarmW_2 { get; set; }

        /// <summary>
        /// 孔深测量当前程序号
        /// </summary>
        public string _02_DMEquActProNo { get; set; }

        /// <summary>
        /// 孔深测量设备本次开机时刻
        /// </summary>
        public DateTimeOffset _02_DMEquStartEquTime { get; set; }

        /// <summary>
        /// 孔深测量开机时间，永不清零（单位:小时）
        /// </summary>
        public double _02_DMEquRunningTime { get; set; }
        #endregion

        #region 缓存台1
        public bool _10_HasWorkpiece_1 { get; set; }

        public short _10_WorkpieceSource_1 { get; set; }

        /// <summary>
        /// 物料码
        /// </summary>
        public string _10_MaterialCode_1 { get; set; }
        #endregion

        #region 缓存台2
        public bool _10_HasWorkpiece_2 { get; set; }

        public short _10_WorkpieceSource_2 { get; set; }

        /// <summary>
        /// 物料码
        /// </summary>
        public string _10_MaterialCode_2 { get; set; }
        #endregion

        #region 缓存台3
        public bool _10_HasWorkpiece_3 { get; set; }

        public short _10_WorkpieceSource_3 { get; set; }

        /// <summary>
        /// 物料码
        /// </summary>
        public string _10_MaterialCode_3 { get; set; }
        #endregion

        #region 缓存台4
        public bool _10_HasWorkpiece_4 { get; set; }

        public short _10_WorkpieceSource_4 { get; set; }

        /// <summary>
        /// 物料码
        /// </summary>
        public string _10_MaterialCode_4 { get; set; }
        #endregion

        #region 缓存台5
        public bool _10_HasWorkpiece_5 { get; set; }

        public short _10_WorkpieceSource_5 { get; set; }

        /// <summary>
        /// 物料码
        /// </summary>
        public string _10_MaterialCode_5 { get; set; }
        #endregion

        #region 缓存台6
        public bool _10_HasWorkpiece_6 { get; set; }

        public short _10_WorkpieceSource_6 { get; set; }

        /// <summary>
        /// 物料码
        /// </summary>
        public string _10_MaterialCode_6 { get; set; }
        #endregion

        #region 上料车1
        public bool _08_AtStation_L1 { get; set; }
        public bool _08_Empty_L1 { get; set; }
        public short _08_WorkpieceNum_L1 { get; set; }

        /// <summary>
        /// 物料码
        /// </summary>
        public string _08_MaterialCode_L1 { get; set; }
        #endregion

        #region 上料车2
        public bool _08_AtStation_L2 { get; set; }
        public bool _08_Empty_L2 { get; set; }
        public short _08_WorkpieceNum_L2 { get; set; }

        /// <summary>
        /// 物料码
        /// </summary>
        public string _08_MaterialCode_L2 { get; set; }
        #endregion

        #region 下料车1
        public bool _08_AtStation_D1 { get; set; }
        public bool _08_Full_D1 { get; set; }
        public short _08_WorkpieceNum_D1 { get; set; }

        /// <summary>
        /// 物料码
        /// </summary>
        public string _08_MaterialCode_D1 { get; set; }
        #endregion

        #region 下料车2
        public bool _08_AtStation_D2 { get; set; }
        public bool _08_Full_D2 { get; set; }
        public short _08_WorkpieceNum_D2 { get; set; }

        /// <summary>
        /// 物料码
        /// </summary>
        public string _08_MaterialCode_D2 { get; set; }
        #endregion

        #region NG料车
        public bool _08_AtStation_NG { get; set; }
        public bool _08_Full_NG { get; set; }
        public short _08_WorkpieceNum_NG { get; set; }

        /// <summary>
        /// 物料码
        /// </summary>
        public string _08_MaterialCode1_NG { get; set; }

        /// <summary>
        /// NG原因
        /// </summary>
        public short _08_Reason1_NG { get; set; }

        /// <summary>
        /// 物料码
        /// </summary>
        public string _08_MaterialCode2_NG { get; set; }

        /// <summary>
        /// NG原因
        /// </summary>
        public short _08_Reason2_NG { get; set; }

        /// <summary>
        /// 物料码
        /// </summary>
        public string _08_MaterialCode3_NG { get; set; }

        /// <summary>
        /// NG原因
        /// </summary>
        public short _08_Reason3_NG { get; set; }

        /// <summary>
        /// 物料码
        /// </summary>
        public string _08_MaterialCode4_NG { get; set; }

        /// <summary>
        /// NG原因
        /// </summary>
        public short _08_Reason4_NG { get; set; }
        #endregion

        #region 扫码器
        public bool _13_StartScanCodeStatus { get; set; }
        public bool _13_AgainStatus { get; set; }
        public bool _13_PassStatus { get; set; }
        public bool _13_ScanCodeBypassStatus { get; set; }
        public bool _13_ScanCodeCom { get; set; }
        public string _13_ScanCodeContent { get; set; }
        public string _13_ScanCodeContent_Enter { get; set; }
        public bool _13_AutoPass { get; set; }
        public bool _13_AutoPassStatus { get; set; }
        public string _13_AutoPassContent { get; set; }
        #endregion

        #region 激光打标
        public bool _06_InitStatus { get; set; }
        public bool _06_StartMarkStatus { get; set; }
        public bool _06_CodeBypassStatus { get; set; }
        public bool _06_EMO { get; set; }
        public bool _06_Ready { get; set; }
        public bool _06_End { get; set; }
        public bool _06_HasWorkpiece { get; set; }
        public bool _06_Com { get; set; }
        public bool _06_InitSuccess { get; set; }
        public bool _06_MarkComplete { get; set; }
        public short _06_WorkpieceSource { get; set; }
        public string _06_MarkContent_Enter { get; set; }

        public string _06_Result { get; set; }

        public string _06_MaterialCode { get; set; }

        public bool _06_ValAct { get; set; }

        /// <summary>
        /// 打标机数据非法或格式不正常
        /// </summary>
        public bool _06_DataPatternError { get; set; }

        /// <summary>
        /// 打标机初始化失败
        /// </summary>
        public bool _06_InitFailed { get; set; }

        /// <summary>
        /// 打标失败
        /// </summary>
        public bool _06_MarkFailed { get; set; }

        /// <summary>
        /// 打码设备状态字
        /// </summary>
        public BitArray _06_PriEquStaW { get; set; }

        /// <summary>
        /// 打码程序状态字
        /// </summary>
        public BitArray _06_PriEquProStaW { get; set; }

        /// <summary>
        /// 打码设备报警字1
        /// </summary>
        public BitArray _06_PriEquAlarmW_1 { get; set; }

        /// <summary>
        /// 打码设备报警字2
        /// </summary>
        public BitArray _06_PriEquAlarmW_2 { get; set; }

        /// <summary>
        /// 打码设备本次开机时刻
        /// </summary>
        public DateTimeOffset _06_PriEquStartEquTime { get; set; }

        /// <summary>
        /// 打码设备开机时间，永不清零（单位:小时）
        /// </summary>
        public double _06_PriEquRunningTime { get; set; }
        #endregion

        #region 机械手
        public bool _09_RestartStatus { get; set; }
        public bool _09_EMO { get; set; }
        public bool _09_Ready { get; set; }
        public bool _09_HasWorkpiece { get; set; }
        public short _09_WorkpieceSource { get; set; }
        public short _09_Grab01 { get; set; }
        public short _09_Grab02 { get; set; }
        public short _09_Put01 { get; set; }
        public short _09_Put02 { get; set; }
        public short _09_Position { get; set; }
        public BitArray _09_MStatus { get; set; }
        public BitArray _09_MAlarm1 { get; set; }
        public BitArray _09_MAlarm2 { get; set; }

        /// <summary>
        /// 机器人存在报警
        /// </summary>
        public bool _09_HasAlarm { get; set; }

        /// <summary>
        /// 机器人自动模式
        /// </summary>
        public bool _09_AtAuto { get; set; }

        /// <summary>
        /// 手动T1模式
        /// </summary>
        public bool _09_MaunalT1 { get; set; }

        /// <summary>
        /// 手动T2模式
        /// </summary>
        public bool _09_ManualT2 { get; set; }

        /// <summary>
        /// 机器人在原位
        /// </summary>
        public bool _09_AtInitPosition { set; get; }

        /// <summary>
        /// 物料码抓手1
        /// </summary>
        public string _09_MaterialCode_G1 { get; set; }

        /// <summary>
        /// 物料码抓手2
        /// </summary>
        public string _09_MaterialCode_G2 { get; set; }

        /// <summary>
        /// 机器人本次开机时刻
        /// </summary>
        public DateTimeOffset _09_RbStartEquTime { get; set; }
        #endregion

        #region 数控车床1
        public int _05_CncStatus_1 { get; set; }
        public int _05_CncOpMode_1 { get; set; }
        public string _05_ProgramName_1 { get; set; }
        public int _05_NcuBootTime_1 { get; set; }
        public double _05_NcuOperationTime_1 { get; set; }
        public double _05_NcuCycleTime_1 { get; set; }
        public string _05_ActToolName_1 { get; set; }
        public int _05_ActDNumber_1 { get; set; }
        public double _05_ActToolBasePosX_1 { get; set; }
        public double _05_ActToolBasePosZ_1 { get; set; }
        public double _05_SpindleSetSpeed_1 { get; set; }
        public double _05_SpindleActSpeed_1 { get; set; }
        public double _05_SpindleSetFeedRate_1 { get; set; }
        public double _05_SpindleActFeedRate_1 { get; set; }
        public double _05_SpindleSpeedOverRate_1 { get; set; }
        public double _05_CutSpeedOverRate_1 { get; set; }
        public double _05_SpindleLoad_1 { get; set; }
        public FineLathe05ProcessData _05_FineLathe05ProcessData_1{ get; set; }

        /// <summary>
        /// 物料码
        /// </summary>
        public string _05_MaterialCode_1 { get; set; }
        #endregion

        #region 数控车床2
        public int _05_CncStatus_2 { get; set; }
        public int _05_CncOpMode_2 { get; set; }
        public string _05_ProgramName_2 { get; set; }
        public int _05_NcuBootTime_2{ get; set; }
        public double _05_NcuOperationTime_2 { get; set; }
        public double _05_NcuCycleTime_2{ get; set; }
        public string _05_ActToolName_2 { get; set; }
        public int _05_ActDNumber_2 { get; set; }
        public double _05_ActToolBasePosX_2 { get; set; }
        public double _05_ActToolBasePosZ_2 { get; set; }
        public double _05_SpindleSetSpeed_2 { get; set; }
        public double _05_SpindleActSpeed_2 { get; set; }
        public double _05_SpindleSetFeedRate_2 { get; set; }
        public double _05_SpindleActFeedRate_2 { get; set; }
        public double _05_SpindleSpeedOverRate_2 { get; set; }
        public double _05_CutSpeedOverRate_2 { get; set; }
        public double _05_SpindleLoad_2 { get; set; }
        public FineLathe05ProcessData _05_FineLathe05ProcessData_2 { get; set; }

        /// <summary>
        /// 物料码
        /// </summary>
        public string _05_MaterialCode_2 { get; set; }
        #endregion

        #region 数控车床3
        public int _05_CncStatus_3 { get; set; }
        public int _05_CncOpMode_3 { get; set; }
        public string _05_ProgramName_3 { get; set; }
        public int _05_NcuBootTime_3 { get; set; }
        public double _05_NcuOperationTime_3 { get; set; }
        public double _05_NcuCycleTime_3 { get; set; }
        public string _05_ActToolName_3 { get; set; }
        public int _05_ActDNumber_3 { get; set; }
        public double _05_ActToolBasePosX_3 { get; set; }
        public double _05_ActToolBasePosZ_3 { get; set; }
        public double _05_SpindleSetSpeed_3 { get; set; }
        public double _05_SpindleActSpeed_3 { get; set; }
        public double _05_SpindleSetFeedRate_3 { get; set; }
        public double _05_SpindleActFeedRate_3 { get; set; }
        public double _05_SpindleSpeedOverRate_3 { get; set; }
        public double _05_CutSpeedOverRate_3 { get; set; }
        public double _05_SpindleLoad_3 { get; set; }
        public FineLathe05ProcessData _05_FineLathe05ProcessData_3 { get; set; }

        /// <summary>
        /// 物料码
        /// </summary>
        public string _05_MaterialCode_3 { get; set; }
        #endregion

        #region 三坐标测量
        public bool _11_BypassStatus { get; set; }
        public bool _11_Ready { get; set; }
        public bool _11_End { get; set; }
        public bool _11_HasWorkpiece { get; set; }
        public short _11_WorkpieceSource { get; set; }
        public string _11_MCode { get; set; }
        public string _11_HandleMachine { get; set; }
        public string _11_GetResult { get; set; }

        public string _11_ProductBatch { get; set; }

        /// <summary>
        /// 三坐标加载文件失败
        /// </summary>
        public bool _11_LoadFileFailed { get; set; }

        /// <summary>
        /// 三坐标测量设备状态字
        /// </summary>
        public BitArray _11_ThreeEquStaW { get; set; }

        /// <summary>
        /// 三坐标测量程序状态字
        /// </summary>
        public BitArray _11_ThreeEquProStaW { get; set; }

        /// <summary>
        /// 三坐标测量设备报警字1
        /// </summary>
        public BitArray _11_ThreeEquAlarmW_1 { get; set; }

        /// <summary>
        /// 三坐标测量设备报警字2
        /// </summary>
        public BitArray _11_ThreeEquAlarmW_2 { get; set; }

        /// <summary>
        /// 三坐标测量当前程序号
        /// </summary>
        public string _11_ThreeEquActProNo { get; set; }

        /// <summary>
        /// 物料码
        /// </summary>
        public string _11_ThreeEquMaterialCode { get; set; }

        /// <summary>
        /// 设备本次开机时刻
        /// </summary>
        public DateTimeOffset _11_ThreeEquStartEquTime { get; set; }

        /// <summary>
        /// 三坐标开机时间，永不清零（单位:小时）
        /// </summary>
        public double _11_ThreeEquRunningTime { get; set; }

        /// <summary>
        /// 测量结果是否超差（1=超差，0=无超差）
        /// </summary>
        public bool _11_ThreeResult { get; set; }

        /// <summary>
        /// 请求反馈三坐标结果数据
        /// </summary>
        public bool _11_ThreeValRequst { get; set; }

        /// <summary>
        /// PC读取写入后=T，PC同时复位
        /// </summary>
        public bool _11_ThreeValAct { get; set; }
        #endregion

        #region 清洗机
        public bool _01_BypassStatus { get; set; }

        public bool _01_EMO { get; set; }

        public bool _01_Ready { get; set; }

        public bool _01_End { get; set; }

        public short _01_WorkpieceSource { get; set; }

        public string _01_MCode { get; set; }

        public BitArray _01_MStatus { get; set; }

        public BitArray _01_MAlarm1 { get; set; }

        public BitArray _01_MAlarm2 { get; set; }

        public long _01_WashTime { get; set; }

        public double _01_WashSpeed { get; set; }

        public DateTimeOffset _01_CleanEquStartEquTime { get; set; }

        public double _01_CleanEquRunningTime { get; set; }

        /// <summary>
        /// 存在报警
        /// </summary>
        public bool _01_HasAlarm { get; set; }

        /// <summary>
        /// 存在错误
        /// </summary>
        public bool _01_HasError { get; set; }
        #endregion
    }
}
